package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.Assert;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private VodConstantProperties vodConstantProperties;

    @Autowired
    private VodService vodService;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Override
    public Map<String, Object> uploadTrack(MultipartFile file) {
        //调用云点播api 实现声音上传
        //初始化对象
        VodUploadClient client = new VodUploadClient(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());
        //SecretId:AKIDhEcrunW3QbcQ4WouoYp02tYmpiQ1c5PZ
        //SecretKey:3wjU4SgiYCew2wdBWnrjRxHOM7g2CNLG
        //构建请求对象
        VodUploadRequest request = new VodUploadRequest();
        //设置上传路径：
        String path = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
        request.setMediaFilePath(path);
        //调用上传功能：
        try {
            VodUploadResponse response = client.upload(vodConstantProperties.getRegion(), request);
            log.info("Upload FileId = {}", response.getFileId());
            //调用数据万象进行声音审核
            //创建map 集合
            HashMap<String, Object> map = new HashMap<>();
            map.put("mediaFileId", response.getFileId());
            map.put("mediaUrl", response.getMediaUrl());
            return map;
        } catch (Exception e) {
            log.error("Upload Err", e);
        }
        return Map.of();
    }

    /*
    保存声音
     */
    @Override
    public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
        TrackInfo trackInfo = new TrackInfo();
        //属性赋值
        BeanUtils.copyProperties(trackInfoVo,trackInfo);
        //用户id
        trackInfo.setUserId(userId);
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
        //ordernum表示声音顺序，等于专辑包含声音总数（include_track_count）+1
        trackInfo.setOrderNum(albumInfo.getIncludeTrackCount() + 1);
        //调用vod的api获取真实数据
        TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
        trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
        trackInfo.setMediaSize(trackMediaInfoVo.getSize());
        trackInfo.setMediaType(trackMediaInfoVo.getType());
        trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
        trackInfoMapper.insert(trackInfo);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);
        //	album_info include_track_count = 0;  +1;
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
        albumInfoMapper.updateById(albumInfo);
    }

    @Override
    public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
        return trackInfoMapper.selectUserTrackPage(trackListVoPage, trackInfoQuery);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeTrackInfo(Long trackId) {
        //获取到声音对象
        //TrackInfo trackInfo = this.getById(trackId);
        //select * from track_info;
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        trackInfoMapper.deleteById(trackId);
        //删除统计;
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, trackId));
        //减少专辑表的包含声音总数
        //获取到专辑对象
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() - 1);
        albumInfoMapper.updateById(albumInfo);
        //处理声音序号; update track_info set order_num = order_num - 1 where album_id = 1 and order_num > 50 and is_deleted = 0
        trackInfoMapper.updateOrderNum(albumInfo.getId(),trackInfo.getOrderNum());
        //删除云点播：
        vodService.deleteMedia(trackInfo.getMediaFileId());
    }

    @Override
    public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
        //修改声音对象;
        TrackInfo trackInfo = this.getById(trackId);
        //获取原来的流媒体Id
        String oldMediaFileId = trackInfo.getMediaFileId();
        //属性拷贝：
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        //考虑如何修改了流媒体数据;
        String mediaFileId = trackInfoVo.getMediaFileId();
        //判断比较
        if (!oldMediaFileId.equals(mediaFileId)){
            //获取最新流媒体数据;
            TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(mediaFileId);
            trackInfo.setMediaDuration(mediaInfo.getDuration());
            trackInfo.setMediaSize(mediaInfo.getSize());
            trackInfo.setMediaType(mediaInfo.getType());
            trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
            //删除旧的流媒体数据
            vodService.deleteMedia(oldMediaFileId);
        }
        //表示修改所有数据
        trackInfoMapper.updateById(trackInfo);
    }

    @Override
    public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> trackListVoPage, Long albumId, Long userId) {
        //  跟用户专辑类型有关系！ 根据用户的身份！ 根免费试听集数有关系!
        //  1.  先查询有多少条声音;
        IPage<AlbumTrackListVo> pageInfo = trackInfoMapper.selectAlbumTrackPage(trackListVoPage, albumId);
        //  根据专辑Id获取专辑对象;
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        //  2.  判断这个用户id 是否为空
        if (null == userId) {
            //  说明未登录; 需要判断专辑的类型; 除免费专辑之外，都需要将声音Id 设置为付费(除试听集数 album_info.tracks_for_free);
            if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())) {
                //  order_num > album_info.tracks_for_free; 需要将这些数据的字段  isShowPaidMark = true;
                //                for (AlbumTrackListVo albumTrackListVo : pageInfo.getRecords()) {
                //                    if (albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree()){
                //                        albumTrackListVo.setIsShowPaidMark(true);
                //                    }
                //                }
                pageInfo.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree()).forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
            }
            //  返回数据;
            return pageInfo;
        }
        //  用户Id 不为空
        if (null != userId) {
            //  声明一个变量 是否需要付费;
            boolean isNeedPay = false;
            //  登录了！ 判断专辑类型: vip 免费； 付费;
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())) {
                //  vip 免费 -- 判断用户身份:
                Result<UserInfoVo> infoVoResult = userInfoFeignClient.getUserInfo(userId);
                Assert.notNull(infoVoResult, "远程调用获取用户信息失败");
                UserInfoVo userInfoVo = infoVoResult.getData();
                Assert.notNull(userInfoVo, "远程调用获取用户信息失败");
                if (0 == userInfoVo.getIsVip() || (1 == userInfoVo.getIsVip() && userInfoVo.getVipExpireTime().before(new Date()))) {
                    //  付费;
                    isNeedPay = true;
                }
            } else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())) {
                //  付费;
                isNeedPay = true;
            }
            //  判断付费情况
            if (isNeedPay) {
                //  当前专辑的哪些声音Id 需要付费！ 6-25; 除去免费试听集数;  (判断这个用户是否购买过专辑或购买过单集声音)
                List<AlbumTrackListVo> albumTrackListPaidList = pageInfo.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree()).collect(Collectors.toList());
                //  需要付费的声音Id;
                List<Long> trackNeedPaidList = albumTrackListPaidList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
                //  远程调用: map.put(trackId,1); map.put(trackId,0); 1:表示已经购买; 0:表示未购买 setIsShowPaidMark(true);
                Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumId,trackNeedPaidList);
                Assert.notNull(mapResult, "远程调用获取用户付费情况失败");
                //  map.put(trackId,1); map.put(trackId,0); 1:表示已经购买; 0:表示未购买 setIsShowPaidMark(true);
                Map<Long, Integer> map = mapResult.getData();
                //  循环遍历集合;
                for (AlbumTrackListVo albumTrackListVo : albumTrackListPaidList) {
                    //  boolean flag = map.get(albumTrackListVo.getTrackId()) == 0?true:false;
                    //  true; false;
                    albumTrackListVo.setIsShowPaidMark(map.get(albumTrackListVo.getTrackId()) == 0);
                }
            }
        }
        //  返回数据
        return pageInfo;
    }

    @Override
    public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
        try {
            //  更新声音播放量; update track_stat stat set stat_num = stat_num + 1 where track_id = 1 and stat_type = '0701' and is_deleted = 0;
            trackStatMapper.updateTrackStat(trackStatMqVo.getCount(),trackStatMqVo.getTrackId(),trackStatMqVo.getStatType());
            //  修改专辑播放记录;
            if (SystemConstant.TRACK_STAT_PLAY.equals(trackStatMqVo.getStatType())){
                //  修改专辑的播放记录;
                albumStatMapper.updateAlbumStat(trackStatMqVo.getCount(),trackStatMqVo.getAlbumId(),SystemConstant.ALBUM_STAT_PLAY);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void saveTrackStat(Long trackId, String statPlay) {
        //保存数据
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statPlay);
        trackStat.setStatNum(new Random().nextInt(10000000));
        trackStatMapper.insert(trackStat);
    }

}
